<template>
    <el-form
        :model="stateArray"
        status-icon
        ref="ruleForm"
        label-width="100px"
        class="demo-ruleForm"
    >
      <el-form-item
          v-for="state in stateArray"
          :label="state.codeTableName" >
        <el-checkbox
            :indeterminate="state.isIndeterminate"
            v-model="state.checkAll"
            @change="handleCheckAllChange(state)"
            border
            size="medium"
        >
          全选
        </el-checkbox>
        <el-checkbox-group v-model="state.checkedOptions" @change="(value)=>{
         handleCheckedOptionsChange(value,state)
      }">
          <el-checkbox
              v-for="option in state.options"
              :label="option.manuname"
              :key="option.id"
          >
            {{option.manuname}}
          </el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item>
        <el-button
            @click="handleSubmit"
            type="primary"
            round
            icon="el-icon-check"
        >
          修改
        </el-button>
      </el-form-item>
    </el-form>

  </template>


<script lang="ts">
import {defineComponent, watch , reactive, ref} from 'vue'
import {updateOptionsData} from "/@/api";
import {errorMessage, successMessage} from "/@/utils/message";
export default defineComponent({
  name:'',
  props:{
    optionsData:{
      require:true,
      type:Array
    }
  },
  setup(props){
    // 定义要素配置数组接口
    interface stateType{
      checkAll:boolean,
      checkedOptions:Array<string>,
      options:Array<string>,
      isIndeterminate:boolean,
      codeTableName:string,
      manus?:Array<object>
    }
    // 生成要素配置数组
    const stateArray=ref<Array<stateType>|null>([])
    // 页面挂载完成后，渲染数据到视图上
    watch(()=>props.optionsData,(data)=>{
      // 从父组件获取数据并渲染到页面上
      initCheckedList(data)
    })

    // 初始化选中列表
    const initCheckedList=(data:any)=>{
      (data as unknown as Array<any>).forEach(item=>{
        /**
         * @param codeTableName 要素名称
         * @param manus 下拉项列表数组
         */
        const {codeTableName,manus}=item
        // 过滤出已启用状态的下拉项
        const checkedArray=manus.filter(item=>item.state===1)
        // 映射已启用状态下拉项中的每一个对象为下拉项文本说明，用于视图显示
        let checkedOptions=checkedArray.map(item=>item.manuname)
        // 判断该要素下拉列表是否全部启用
        let checkAll=checkedArray.length===manus.length
        // 判断该要素下拉列表是否部分启用
        let isIndeterminate=checkedArray.length>0&&checkedArray.length<manus.length
        const state = reactive<stateType>({
          checkAll,
          checkedOptions,
          options: manus,
          isIndeterminate,
          codeTableName
        });
        stateArray.value.push(state)
      })
    }
    // 处理全选操作
    const handleCheckAllChange = (state) => {
      // 当全选框被选中时，让所有子选项被选中，否则，将所有子选项置于未选中状态
      state.checkedOptions = state.checkAll ?state.options.map(item=>item.manuname) : []
      // 移除全选框的部分选中的样式
      state.isIndeterminate = false;
    };
    // 选择项发生改变的处理事件
    const handleCheckedOptionsChange = (value,state) => {
      const checkedCount = value.length;
      // 当选中项的个数等于总的可选项个数，设置全选框为选中
      state.checkAll = checkedCount === state.options.length;
      // 如果选中项个数大于0，并且小于可选项个数，将全选框设置为部分选中
      state.isIndeterminate = checkedCount > 0 && checkedCount < state.options.length;
    };
    const handleSubmit=async ()=>{
      const menuNameAndCodeTableNames:Array<object>=stateArray.value.map(item=>{
        return {
          codeTableName:item.codeTableName,
          //@ts-ignore
          manus:item.options.map(option=>({...option,state:item.checkedOptions.includes(option.manuname)?1:0}))
        }
      })
      try{
        const res=await updateOptionsData(menuNameAndCodeTableNames)
        if(res===1){
          successMessage('修改配置成功！')
        }else{
          errorMessage('网络错误！')
        }
      }catch (e) {
          errorMessage('网络错误！')
      }
    }
    return {
      stateArray,
      handleCheckAllChange,
      handleCheckedOptionsChange,
      handleSubmit
    };
  }
})
</script>

<style lang='scss' scoped>

</style>
